home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / MOVE_WM.ZIP / MOVE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-06  |  7.5 KB  |  331 lines

  1. #include    <string.h>
  2. #include    <stdio.h>
  3. #include    <conio.h>
  4. #include    <dos.h>
  5. #include    <process.h>
  6.  
  7. #define    FILE_NOT_FOUND    0x02        //    Error Code        //
  8. #define PATH_NOT_FOUND    0x03        //    Error Code        //
  9. #define ACCESS_DENIED    0x05        //    Error Code        //
  10. #define    NOT_SAME_DEVICE    0x11        //    Error Code        //
  11. #define NO_FILES_LEFT    0x12        //    Error Code        //
  12. #define    MOVE_FILE    0x5600        //    Documented Call        //
  13. #define SERVER_CALL    0x5D00        //    Undocumented Call    //
  14. #define CANONICAL_NAMES    0x60        //    Undocumented Call    //
  15. #define DOS_SERVICES    0x21        //    INT 21h DOS services    //
  16. #define SUCCESS        0        //    Useful Boolean        //
  17. #define CARRY_FLAG    1        //    Carry flag bit position    //
  18.  
  19. #define COPYRIGHT  "Released into Public Domain by Walt Myers, 1993.  \
  20. CIS 76407,2235"
  21.  
  22. void    argument_error(void);
  23. void    check_result(void);
  24. void    clean_up(int a);
  25. void    get_canonical_names(void);
  26. int    move_file(void);
  27. void    set_registers(void);
  28.  
  29. struct source
  30.  
  31. {
  32. char path[128];
  33. char canonical_path[128];
  34. } old;
  35.  
  36. struct destination
  37.  
  38. {
  39. char path[128];
  40. char canonical_path[128];
  41. } new;
  42.  
  43. struct    // This is the DOS parameter list for INT 21h, function 0x5D00    //
  44.  
  45. {
  46. unsigned int ax;
  47. unsigned int bx;
  48. unsigned int cx;
  49. unsigned int dx;
  50. unsigned int si;
  51. unsigned int di;
  52. unsigned int ds;
  53. unsigned int es;
  54. unsigned int reserved;
  55. unsigned int computer_ID;    //    Set to 0h for current machine    //
  56. unsigned int process_ID;    //    The PSP for this program    //
  57.  
  58. } DOS_parameter_list;
  59.  
  60. unsigned int data_segment;
  61. unsigned int extra_segment;
  62. unsigned int ax;
  63. unsigned int canonical_ds,canonical_dx,canonical_es,canonical_di,flags;
  64. unsigned int relative_ds,relative_dx,relative_es,relative_di,flags;
  65. unsigned int relative_si;
  66. unsigned int psp;
  67.  
  68. int result;
  69.  
  70.  
  71. void    main(int argc, char **argv)
  72.  
  73. {
  74. if (argc != 3) argument_error();    //    Check arguments        //
  75. (void)strcpy(old.path, argv[1]);    //    Copy in arguments    //
  76. (void)strcpy(new.path, argv[2]);    //    Copy in arguments    //
  77. set_registers();            //    Initialize registers    //
  78. get_canonical_names();            //    Get true names        //
  79. result = move_file();            //    Move the file        //
  80. clean_up(result);            //    Quit            //
  81.  
  82. }                    //    End main        //
  83.  
  84.  
  85. void    argument_error(void)
  86.  
  87. {
  88.  
  89. puts("\nItems in [] are optional. All others are required.");
  90. puts("\nUsage is move [path]\\filename [path]\\filename");
  91. puts("Wildcards (?,*) are OK.  Can't move to different drive.\n");
  92. puts(COPYRIGHT);
  93. exit(1);
  94.  
  95. }                    //    End function        //
  96.  
  97.  
  98. void    check_result(void)
  99.  
  100. {
  101.  
  102. if ((flags & CARRY_FLAG) == SUCCESS) return;    //    OK        //
  103.  
  104. switch(ax)
  105.  
  106. {
  107.     case (0x02):
  108.  
  109.         puts("Invalid source name");
  110.         puts(COPYRIGHT);
  111.         exit(1);
  112.  
  113.     case (0x03):
  114.  
  115.         puts("Invalid drive or malformed path");
  116.         puts(COPYRIGHT);
  117.         exit(1);
  118.  
  119.     default:
  120.  
  121.         printf("Error = %d getting canonical names\n", ax);
  122.         puts(COPYRIGHT);
  123.         exit(1);
  124.  
  125.  
  126. }                    //    End switch        //
  127.  
  128. }                    //    End function        //
  129.  
  130.  
  131. void    clean_up(int a)
  132.  
  133. {
  134.  
  135. _DS = data_segment;            //    Reset data segment    //
  136. _ES = extra_segment;            //    Reset extra segment    //
  137.  
  138. switch(a)                //    Check result        //
  139.  
  140. {
  141.  
  142.     case SUCCESS:
  143.     case NO_FILES_LEFT:
  144.         puts("File(s) moved successfully");
  145.         puts(COPYRIGHT);
  146.         break;
  147.  
  148.     case FILE_NOT_FOUND:
  149.         puts("File not found");
  150.         puts(COPYRIGHT);
  151.         exit(1);
  152.  
  153.     case PATH_NOT_FOUND:
  154.         puts("Path not found");
  155.         puts(COPYRIGHT);
  156.         exit(1);
  157.  
  158.     case ACCESS_DENIED:
  159.         puts("Root directory full, file already exists or \
  160. access denied.");
  161.         puts(COPYRIGHT);
  162.         exit(1);
  163.  
  164.     case NOT_SAME_DEVICE:
  165.         puts("Must move to same drive");
  166.         puts(COPYRIGHT);
  167.         exit(1);
  168.  
  169.     default:
  170.         printf("Unknown errorcode = %d\n", a);
  171.         puts(COPYRIGHT);
  172.  
  173. }                    //    End switch        //
  174.  
  175. }                    //    End function        //
  176.  
  177.  
  178. void    get_canonical_names(void)
  179.  
  180. {
  181.  
  182. /*      For INT 21h, function 60h:
  183.  
  184.     Call with:
  185.  
  186.     AH:    60h
  187.     DS:SI    Pointer to ASCIZ relative path string or filename
  188.     ES:DI    Pointer to 128 byte buffer for ASCIZ canonical
  189.         fully qualified name
  190.  
  191.     Returns:
  192.         CF set on error
  193.             AX    error code
  194.                 02h    invalid source name
  195.                 03h    invalid or malformed path
  196.  
  197.         CF clear if successful
  198.             AH    0h
  199.             AL    Destroyed
  200.             Buffer filled with qualified name.
  201.  
  202.                                     */
  203.  
  204. //        Do the from, or the old, first                //
  205.  
  206. relative_ds = FP_SEG(old.path);
  207. relative_si = FP_OFF(old.path);
  208. canonical_es = FP_SEG(old.canonical_path);
  209. canonical_di = FP_OFF(old.canonical_path);
  210.  
  211. _AH = CANONICAL_NAMES;            //    Load registers        //
  212. _DS = relative_ds;
  213. _SI = relative_si;
  214. _ES = canonical_es;
  215. _DI = canonical_di;
  216.  
  217. geninterrupt(DOS_SERVICES);        //    Get canonical names    //
  218. check_result();                //    Check result        //
  219. flags = _FLAGS;                //    Load variable        //
  220. ax = _AX;                //    Load variable        //
  221.  
  222. _DS = data_segment;            //    Reset _DS        //
  223.  
  224. //        Do the to, or the new, next                //
  225.  
  226. relative_ds = FP_SEG(new.path);
  227. relative_si = FP_OFF(new.path);
  228. canonical_es = FP_SEG(new.canonical_path);
  229. canonical_di = FP_OFF(new.canonical_path);
  230.  
  231. _AH = CANONICAL_NAMES;            //    Load registers        //
  232. _DS = relative_ds;
  233. _SI = relative_si;
  234. _ES = canonical_es;
  235. _DI = canonical_di;
  236.  
  237. geninterrupt(DOS_SERVICES);        //    Get canonical names    //
  238. flags = _FLAGS;                //    Load variable        //
  239. ax = _AX;                //    Load variable        //
  240. check_result();                //    Check result        //
  241.  
  242. _DS = data_segment;            //    Reset _DS        //
  243.  
  244. //    Now that buffers are loaded, set up variables for move call    //
  245.  
  246. canonical_ds = FP_SEG(old.canonical_path);    // Old canonical path    //
  247. canonical_dx = FP_OFF(old.canonical_path);
  248.  
  249. // Variables for the new path are set above (canonical_es,di)        //
  250.  
  251.  
  252. }                    //    End function        //
  253.  
  254.  
  255. int    move_file(void)
  256.  
  257. {
  258.  
  259. unsigned int ax;
  260.  
  261. /*    For moving files, it's INT 21h, function 5D00h (undocumented
  262.     behavior with 5D00h lets you use wild cards.  Using the
  263.     documented function 56h doesn't permit the use of wild cards).
  264.  
  265.     Call with:
  266.         AH    5Dh
  267.         DS:DX    Pointer to DOS parameter list where DPL
  268.             contains all the necessary information for
  269.             it's own call to INT 21h.  So, fill the DPL
  270.             with all the right information for a function
  271.             56h call.
  272.  
  273.     For a function 56h call:
  274.  
  275.     Call with:
  276.         AH    56h
  277.         DS:DX    Pointer to ASCIZ old filespec
  278.         ES:DI    Pointer to ASCIZ new filespec
  279.  
  280.     Note:      When invoked by function 5D00, (like we're doing here),
  281.         both source and destination filespec must be canonical
  282.         as returned by function 60h.
  283.                                     */
  284.  
  285.  
  286.  
  287. //        Load the DOS parameter list                //
  288.  
  289. DOS_parameter_list.ax = MOVE_FILE;        //    Move file function    //
  290. DOS_parameter_list.bx = _BX;
  291. DOS_parameter_list.cx = _CX;
  292. DOS_parameter_list.dx = canonical_dx;     //    Old path offset        //
  293. DOS_parameter_list.si = _SI;
  294. DOS_parameter_list.di = canonical_di;    //    New path offset        //
  295. DOS_parameter_list.ds = canonical_ds;    //    Old path segment    //
  296. DOS_parameter_list.es = canonical_es;    //    New path segment    //
  297. //DOS_parameter_list.reserved            Comment out this one    //
  298. DOS_parameter_list.computer_ID =0x0000;//    Current system        //
  299. DOS_parameter_list.process_ID = psp;    //    psp for this program    //
  300.  
  301. //    Call the server interrupt which will call int 21 with the    //
  302. //    parameters listed above.                    //
  303.  
  304. _DS = FP_SEG(&DOS_parameter_list);    //    Segment of DPL        //
  305. _DX = FP_OFF(&DOS_parameter_list);    //    Offset of DPL        //
  306. _AX = SERVER_CALL;            //    Server Call        //
  307.  
  308. geninterrupt(DOS_SERVICES);        //    Server Function Call    //
  309.  
  310. _DS = data_segment;            //    Reset data segment    //
  311.  
  312. ax = _AX;                //    Store register        //
  313. flags =_FLAGS;                //    Save _FLAGS        //
  314. result = (flags & CARRY_FLAG);        //    Get carry flag        //
  315.  
  316. if (result != SUCCESS) result = ax;    //    Load result variable    //
  317.  
  318. return(result);
  319.  
  320. }                    //    End function        //
  321.  
  322.  
  323. void    set_registers(void)
  324.  
  325. {
  326.  
  327. data_segment = _DS;            //    Save current segments    //
  328. extra_segment= _ES;            //    Save current segments    //
  329. psp = getpsp();                //    Get psp            //
  330.  
  331. }